#include <scott/Utility.h>

BOOST_AUTO_TEST_SUITE( UtilityFormat_Test_Suite )

BOOST_AUTO_TEST_CASE( Format_Test )
{
	// Variables creation
	SEnumTypeDescriptorSp colorsTd = SEnumTypeDescriptor::Create("plugin", "colors", "");
	colorsTd->AddEntry("red", 0, "red color");			
	colorsTd->AddEntry("yellow", 1, "yellow color");
	colorsTd->AddEntry("green", 2, "green color");

	SVectorTypeDescriptorSp vstringTd = SVectorTypeDescriptor::Create("plugin", "vstring", "", STypeString);
	SVectorTypeDescriptorSp vnumberTd = SVectorTypeDescriptor::Create("plugin", "vnumber", "", STypeNumber);
	SVectorTypeDescriptorSp bufferTd = SVectorTypeDescriptor::Create("plugin", "buffer", "", STypeByte);
	SVectorTypeDescriptorSp vcolorsTd = SVectorTypeDescriptor::Create("plugin", "vcolors", "", colorsTd);

	SVectorTypeDescriptorSp matrixTd = SVectorTypeDescriptor::Create("plugin", "matrix", "", vnumberTd);

	SStructTypeDescriptorSp sstruct1Td = SStructTypeDescriptor::Create("plugin", "sstruct", "");
	sstruct1Td->AddMember("str", "", STypeString);
	sstruct1Td->AddMember("num", "", STypeNumber);
	sstruct1Td->AddMember("c", "", STypeChar);
	sstruct1Td->AddMember("b", "", STypeByte);

	SStructTypeDescriptorSp sstruct2Td = SStructTypeDescriptor::Create("plugin", "sstruct2", "");
	sstruct2Td->AddMember("vs", "", vstringTd);
	sstruct2Td->AddMember("buf", "", bufferTd);
	sstruct2Td->AddMember("m", "", matrixTd);
	sstruct2Td->AddMember("s1", "", sstruct1Td);

	SVectorTypeDescriptorSp vsstruct2Td = SVectorTypeDescriptor::Create("plugin", "vsstruct", "", sstruct2Td);

	SValueSpMapSp vars( new SValueSpMap() );
	(*vars)["b"] = SByte::Create(10);
	(*vars)["n"] = SNumber::Create(1000);
	(*vars)["c"] = SChar::Create('C');
	(*vars)["s"] = SString::Create("Hello");
	(*vars)["vn"] = SVector::Parse(vnumberTd, "{1,2,3}");
	(*vars)["buf"] = SVector::Parse(bufferTd, "0x001122334455");
	(*vars)["vs"] = SVector::Parse(vstringTd, "{\"One\",\"Two\",\"Three\"}");
	(*vars)["vcol"] = SVector::Parse(vcolorsTd, "{ red, yellow, green }");
	(*vars)["m"] = SVector::Parse(matrixTd, "{ {1,2,3}, {4,5,6}, {7,8,9} }");
	(*vars)["s1"] = SStruct::Parse(sstruct1Td, "{ \"Hello\", 10, 'C', 0xFF }");
	(*vars)["s2"] = SStruct::Parse(sstruct2Td, "{ {\"1\",\"2\"}, 0x001122, { {1,2}, {3,4} }, { \"Hello\", 10, 'C', 0xFF } }");
	(*vars)["s2_0"] = SStruct::Parse(sstruct2Td, "{ {\"1\",\"2\"}, 0x001122, { {1,2}, {3,4} }, { \"Hello\", 10, 'C', 0xFF } }");
	(*vars)["s2_1"] = SStruct::Parse(sstruct2Td, "{ {\"1\",\"2\"}, 0x001122, { {1,2}, {3,4} }, { \"Hello\", 10, 'C', 0xFF } }");
	(*vars)["s2_2"] = SStruct::Parse(sstruct2Td, "{ {\"1\",\"2\"}, 0x001122, { {1,2}, {3,4} }, { \"Hello\", 10, 'C', 0xFF } }");

	SVectorSp vs2 = SVector::Create(vsstruct2Td);
	vs2->AddItem( (*vars)["s2_0"] );
	vs2->AddItem( (*vars)["s2_1"] );
	vs2->AddItem( (*vars)["s2_2"] );
	(*vars)["vs2"] = vs2;

	// Testing...
	BOOST_CHECK( Utility::Format( "Hello", "", vars ) == "Hello" );
	BOOST_CHECK( Utility::Format( "Hello\\{0,d\\}", "", vars ) == "Hello{0,d}" );
	BOOST_CHECK_THROW( Utility::Format( "Hello{}", "", vars ), SException );

	BOOST_CHECK( Utility::Format( "Byte: {0}", "100", vars ) == "Byte: 100" );
	BOOST_CHECK( Utility::Format( "Byte: {0,d}", "100", vars ) == "Byte: 100" );
	BOOST_CHECK( Utility::Format( "Byte: {0,x}", "100", vars ) == "Byte: 0x64" );
	BOOST_CHECK( Utility::Format( "Byte: {0,d}", "b", vars ) == "Byte: 10" );

	BOOST_CHECK( Utility::Format( "Char: {0}", "'M'", vars ) == "Char: 'M'" );
	BOOST_CHECK( Utility::Format( "Char: {0,c}", "'M'", vars ) == "Char: 'M'" );
	BOOST_CHECK( Utility::Format( "Char: {0}", "c", vars ) == "Char: 'C'" );

	BOOST_CHECK( Utility::Format( "Number: {0}", "1000", vars ) == "Number: 1000" );
	BOOST_CHECK( Utility::Format( "Number: {0,d}", "1000", vars ) == "Number: 1000" );
	BOOST_CHECK( Utility::Format( "Number: {0,x}", "1000", vars ) == "Number: 0x3E8" );
	BOOST_CHECK( Utility::Format( "Number: {0}", "n", vars ) == "Number: 1000" );

	BOOST_CHECK( Utility::Format( "String: {0}", "\"Hello\"", vars ) == "String: \"Hello\"" );
	BOOST_CHECK( Utility::Format( "String: {0,s}", "s", vars ) == "String: \"Hello\"" );
	BOOST_CHECK( Utility::Format( "String: {0}", "s", vars ) == "String: \"Hello\"" );

	BOOST_CHECK( Utility::Format( "Byte: {0}\nChar: {1}\nNumber: {2}\nString: {3}","b c n s", vars ) 
		                       == "Byte: 10\nChar: 'C'\nNumber: 1000\nString: \"Hello\"" );
	BOOST_CHECK( Utility::Format( "{0}-{1}-{0}-{2}-{1}-{0,2x}-{2,5nx}","b c n", vars ) 
		                       == "10-'C'-10-1000-'C'-0x0A-003E8" );
}

BOOST_AUTO_TEST_SUITE_END()
